using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using FluentDBC.DomainModel;
using FluentDBC.Extensions;

namespace FluentDBC.Default
{
    public class FieldContract<TModel> : IFieldContract<TModel>
    {
        private readonly IFluentDBCConfiguration _codeContractFactory;

        public Type ClassObj { get; private set; }

        public FieldContract(IFluentDBCConfiguration codeContractFactory, Type classObj)
        {
            _codeContractFactory = codeContractFactory;
            ClassObj = classObj;
        }

        public IConditionEngine<TModel> Field<TProperty>(Expression<Func<TModel, TProperty>> expr)
        {
            PropertyInfo propertyInfo;

            if (expr.Body is MemberExpression)
            {
                propertyInfo = ((MemberExpression)expr.Body).Member as PropertyInfo;
            }
            else
            {
                propertyInfo = ((MemberExpression)((UnaryExpression)expr.Body).Operand).Member as PropertyInfo;
            }

            for (int i = 0; i < _codeContractFactory.ClassContracts.Count; i++)
            {
                var element = _codeContractFactory.ClassContracts.ElementAt(i);

                if (element.Type.TypeCompare(ClassObj))
                {
                    element.Fields.Add(new Field { FieldName = propertyInfo.Name });
                }
            }

            return new ConditionEngine<TModel>(_codeContractFactory, this, propertyInfo.Name);
        }

        public IFluentDBCConfiguration Completed()
        {
            return _codeContractFactory;
        }
    }
}